package win.devhu.testing.simple

import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import java.io.FileReader

/**
 * Gson 常用操作示例
 * */

//Person 数据类，用于处理JSON Str时实体映射
data class Person(val name: String, val age: Int, val messages: List<String>) {
}

fun main(args: Array<String>) {

    //比较常见的略微复杂的JSON数据格式
    val jsonStr = "[\n" +
            "    {\n" +
            "        \"name\": \"窗边的小豆豆\",\n" +
            "        \"age\": \"9\",\n" +
            "        \"messages\": [\n" +
            "            \"优秀的少先队员\",\n" +
            "            \"勤劳的小蜜蜂\"\n" +
            "        ]\n" +
            "    },\n" +
            "    {\n" +
            "        \"name\": \"聪明的顺溜\",\n" +
            "        \"age\": 15,\n" +
            "        \"messages\": [\n" +
            "            \"优秀的共青团员\",\n" +
            "            \"喜欢隔壁的班花却不敢表白\"\n" +
            "        ]\n" +
            "    }\n" +
            "]"

    //方式一：直接访问取值临时使用，复杂操作时不建议
    val jParser = JsonParser()
    val jsonArr = jParser.parse(jsonStr)  as JsonArray //json str to JsonArray
    println("name: ${jsonArr[0].asJsonObject.get("name").asString}")

    //方式二：建立一个映射类,Kotin直接使用数据类很方便
    val gson = Gson()
    val json = jsonArr.get(0).asJsonObject.toString()     //json str
    val person1 : Person = gson.fromJson(json, Person::class.java)  //json str 转成实体类
    println(person1.name)   //json str 转成实体类后操作，对于复杂的JSON文件来说更方便

    //加载JSON文件，默认FileReader 获取文件路径为项目根目录，返回的其实是文件流，暂时忽略其他路径下文件获取。
    val person2: Person = gson.fromJson(FileReader("tmp/person.json"), Person::class.java)
    println(person2.name)
    //Date数据类转JSON Str
    val person3 = Person("隔壁老王", 27, listOf("失业人员", "人称三和大神"))
    val jsonPerson: String = gson.toJson(person3)
    println(jsonPerson)

    //TypeToken 反射机制，json list Str to json list
    var personList: List<Person> = gson.fromJson(jsonStr, object : TypeToken<List<Person>>() {}.type)
    personList.forEach { println(it) }

    //List 转成 JSON Str
    val jsonPersonList: String = gson.toJson(personList)
    println(jsonPersonList)

    //Gson 与 Map 的互转
    var personMap: Map<String, Any> = gson.fromJson(json, object : TypeToken<Map<String, Any>>() {}.type)
    personMap.forEach { println(it) }

    val jsonPersonMap: String = gson.toJson(personMap)
    println(jsonPersonMap)

}